package org.manager.units;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.manager.generic.Repository.GenericHibernateRepository;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.stereotype.Repository;

/**
 * 系统单位管理DAO
 * 
 * @author zxf_noimp
 * 
 */
@SuppressWarnings("unchecked")
@Repository("sysUnitsRepository")
public class SysUnitsRepositoryImpl extends
		GenericHibernateRepository<SysUnits> implements SysUnitsRepository {

	// @Override
	public List<SysUnits> findPageSysUnits(final SysUnits sysunit,
			final int start, final int limit) {
		List<SysUnits> sysUnitList = getHibernateTemplate().executeFind(
				new HibernateCallback() {
					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
						return session.createCriteria(SysUnits.class).add(
								Example.create(sysunit).excludeProperty("propertiesCount")).setFirstResult(
								start * limit).setMaxResults(limit).list();
					}
				});
		return sysUnitList;
	}

	// @Override
	public int totalRecord(final SysUnits sysunit) {
		return (Integer) getHibernateTemplate().execute(
				new HibernateCallback() {
					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
						return session.createCriteria(SysUnits.class).add(
								Example.create(sysunit).excludeProperty("propertiesCount")).setProjection(
								Projections.rowCount()).uniqueResult();
					}
				});
	}

	@Override
	public SysUnits findSysUnitsByEntity(final String unitCode) {
		return (SysUnits) this.getHibernateTemplate().execute(
				new HibernateCallback() {
					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
						SysUnits units = null;
						Iterator it = session.createQuery(
								"from SysUnits where unitCode=:unitCode")
								.setParameter("unitCode", unitCode).list()
								.iterator();
						while (it.hasNext()) {
							units = (SysUnits) it.next();
							session.evict(units);
						}
						return units;
					}
				});
	}
	
	public List<SysUnits> findBySysUnits(final SysUnits sysunit) {
		List<SysUnits> sysUnitList = getHibernateTemplate().executeFind(
				new HibernateCallback() {
					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
						return session.createCriteria(SysUnits.class).add(
								Example.create(sysunit).excludeProperty("propertiesCount")).list();
					}
				});
		return sysUnitList;
	}
	
	public Serializable addSysUnits(final SysUnits pro) {
		//添加的时候需要将节点上一级的code和本级code相加: 1.1
		String parentCode = "";
		if(StringUtils.isNotBlank(pro.getUnitParentId())){
			//查询父参数.获得父参数的code.
			SysUnits parent = (SysUnits)getHibernateTemplate().execute(new HibernateCallback(){
				public Object doInHibernate(Session session)
						throws HibernateException, SQLException {
					List l = session.createCriteria(SysUnits.class).add(Restrictions.eq("id", pro.getUnitParentId())).list();
					if(l != null && l.size() > 0){
						return l.get(0);
					}
					return null;
				}
			});
			if(parent == null) return null;
			parentCode = parent.getUnitCode()+".";
			if(StringUtils.isBlank(parentCode)) return null;
		}
			//查询本级参数中,最小的code.
			List<SysUnits> propertiesList = getHibernateTemplate().executeFind(new HibernateCallback(){
				public Object doInHibernate(Session session)
						throws HibernateException, SQLException {
					Criterion c;
					if(StringUtils.isBlank(pro.getUnitParentId())){
						c = Restrictions.isNull("unitParentId");
					}else{
						c = Restrictions.eq("unitParentId", pro.getUnitParentId());
	 				}
					return session.createCriteria(SysUnits.class).add(c).list();
				}
			});
			int maxCode = 0;
			for(SysUnits p : propertiesList){
				String code = p.getUnitCode();
				if(code != null && code.lastIndexOf(".") > -1){
					code = code.substring(code.lastIndexOf(".")+1, code.length());
				}
				if(NumberUtils.isNumber(code) && NumberUtils.toInt(code)>maxCode){
					maxCode = NumberUtils.toInt(code);
				}
			}
			pro.setUnitCode(parentCode+(maxCode+1));
		return save(pro);
	}

	
	@Override
	public List<SysUnits> findAll() {
		return (List<SysUnits>)getHibernateTemplate().execute(new HibernateCallback(){
			@Override
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				Iterator it = session.createQuery("from SysUnits ORDER by unitCode").iterate();
				List<SysUnits> unitList = new ArrayList<SysUnits>();
				SysUnits unit;
				while(it.hasNext()){
					unit = (SysUnits)it.next();
					SysUnits voUnit = new SysUnits();
					try {
						BeanUtils.copyProperties(voUnit, unit);
					} catch (Exception e) {
						e.printStackTrace();
					} 
					unitList.add(voUnit);
				}
				unit = null;
				it = null;
				return unitList;
			}
		});
	}
	
}
